package mytest;

import com.hazelcast.config.Config;
import com.hazelcast.config.GroupConfig;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;
import io.vertx.core.dns.AddressResolverOptions;
import io.vertx.core.http.HttpClient;
import io.vertx.core.json.JsonObject;
import io.vertx.core.spi.cluster.ClusterManager;
import io.vertx.servicediscovery.Record;
import io.vertx.servicediscovery.ServiceDiscovery;
import io.vertx.servicediscovery.ServiceDiscoveryOptions;
import io.vertx.servicediscovery.ServiceReference;
import io.vertx.servicediscovery.types.HttpEndpoint;
import io.vertx.spi.cluster.hazelcast.HazelcastClusterManager;

/**
 * @Author Ldj
 * @Date 2017/10/31 15:41
 * @Description 服务发现测试
 */
public class discovery extends AbstractVerticle{

    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();
        Config cfg = new Config();
        // 加入组的配置，防止广播环境下，负载串到别的开发机中
        GroupConfig group = new GroupConfig();
        group.setName("p-dev");
        group.setPassword("p-dev");
        cfg.setGroupConfig(group);
        // 申明集群管理器
        ClusterManager mgr = new HazelcastClusterManager(cfg);
        VertxOptions options = new VertxOptions();
        options.
                setWorkerPoolSize(40)
                .setClustered(true)
                .setHAEnabled(true)
                .setClusterPort(7001)
                .setClusterManager(mgr)
                .setHAGroup("test-service")
                .setAddressResolverOptions(new AddressResolverOptions()
                        .addServer("127.0.0.1:8001").addServer("127.0.0.1:8002"));
        // 集群化vertx
        Vertx.clusteredVertx(options, ar -> {
            if (ar.succeeded()) {
                System.out.println("successfully clusteredVertx!");
                Vertx vert = ar.result();
            } else {
                System.out.println("cluster failed, using default vertx");
            }
        });
        vertx.deployVerticle(discovery.class.getName());
    }
    @Override
    public void start() {
        ServiceDiscovery discovery = ServiceDiscovery.create(vertx,
                new ServiceDiscoveryOptions()
                        .setAnnounceAddress("service-announce")
                        .setName("my-name"));

        //create a new custom record
        Record record1 = new Record()
                .setType("eventbus-service-proxy")
                .setLocation(new JsonObject().put("endpoint", "the-service-address"))
                .setName("my-service")
                .setMetadata(new JsonObject().put("some-label", "some-value"));
        //publish "my-service" service
        discovery.publish(record1, ar -> {
            if (ar.succeeded()) {
                System.out.println("\"" + record1.getName() + "\" successfully published!");
                Record publishedRecord = ar.result();
            } else {
                // publication failed
            }
        });

        // create a record from type
        Record record2 = HttpEndpoint.createRecord("some-rest-api", "localhost", 8080, "/api");

        //publish the service
        discovery.publish(record2, ar -> {
            if (ar.succeeded()) {
                System.out.println("\"" + record2.getName() + "\" successfully published!");
                Record publishedRecord = ar.result();
            } else {
                // publication failed
            }
        });

        //unpublish "my-service"
        discovery.unpublish(record1.getRegistration(), ar -> {
            if (ar.succeeded()) {
                System.out.println("\"" + record1.getName() + "\" successfully unpublished");
            } else {
                // cannot un-publish the service, may have already been removed, or the record is not published
            }
        });

        //consuming a service
        discovery.getRecord(r -> r.getName().equals(record2.getName()), ar -> {
            if (ar.succeeded()) {
                if (ar.result() != null) {
                    // Retrieve the service reference
                    ServiceReference reference = discovery.getReference(ar.result());
                    // Retrieve the service object
                    HttpClient client = reference.get();
                    System.out.println("Consuming \"" + record2.getName() + "\"");

                    client.getNow("/api", response -> {
                        //release the service
                        reference.release();

                    });
                }
            }
        });

        discovery.close();
    }

}
